﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Fis.Win.Forms
{
    public partial class ReportBaseForm : BaseForm
    {
        protected Fis.Win.Utils.ReportUtils utils;
        protected int[] resetColumns = new int[0];
        protected DevExpress.XtraGrid.GridControl theGridControl { get; set; }

        public string RangeFilter = string.Empty;
        public string AccFilter = string.Empty;
        /// <summary>
        /// 当前期间
        /// </summary>
        protected int CurrentRange;

        public override string Message
        {
            get
            {
                return iMessage.Caption;
            }
            set
            {
                iMessage.Caption = value;
                ShowMessage(value);
            }
        }

        public ReportBaseForm()
        {
            InitializeComponent();
        }

        public ReportBaseForm(object other)
        {
            InitializeComponent();
            InitializeViewUI();
            InitializeBinding();
        }

        public override void InitializeBinding()
        {
            //this.Invoke(new Action(() =>
            //{
                using (DevExpress.Utils.WaitDialogForm wdf = new DevExpress.Utils.WaitDialogForm("正在加载请等待。。。", "数据处理"))
                {
                    var schema = InitializeSchema();
                    utils = InitializeData(schema);
                    InitializeResetColumns(schema);
                    theGridControl.DataSource = schema;
                }
            //}) as Delegate);
        }

        protected virtual DataTable InitializeSchema() { return new DataTable(); }

        protected virtual Fis.Win.Utils.ReportUtils InitializeData(DataTable dt) { return new Utils.ReportUtils(dt); }

        protected virtual void InitializeResetColumns(DataTable data)
        {
            foreach (var i in resetColumns.AsParallel())
            {
                foreach (var d in data.AsEnumerable())
                {
                    var value = ParseExpress(d[i]);
                    if (value != null)
                        d[i] = string.Format("{0:#0,0.00}", value);
                    else
                        d[i] = value;
                }
            }
        }

        /// <summary>
        /// 解析表达式
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        protected virtual object ParseExpress(object exp)
        {
            if (Agile.Engine.Utils.StringUtils.IsEmpty(exp))
                return null;

            var split = exp.ToString().Split(new char[] { '+', '-' }, StringSplitOptions.RemoveEmptyEntries);

            Dictionary<string, decimal> dic = new Dictionary<string, decimal>();
            Fis.Win.Utils.ReportMethodRegistry report = new Utils.ReportMethodRegistry();

            foreach (var s in split)
            {
                var method = s.Substring(0, s.IndexOf('('));
                var args = s.Substring(method.Length + 1, s.Length - method.Length - 2).Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                object[] param = new object[args.Length];
                for (int i = 0; i < args.Length; i++)
                {
                    param[i] = int.Parse(args[i]);
                }

                var value = (decimal)report.MethodInvoke(utils, method, param);
                dic[s] = value;
            }

            var express = exp.ToString();
            decimal result = 0m;

            if (dic.Count == 1)
            {
                result = dic.Values.ToArray()[0];
            }
            else
            {
                var keys = dic.Keys.ToArray(); ;
                char func = '+';

                for (int i = 0; i < keys.Length; i++)
                {
                    if (i == 0)
                    {
                        result = dic[keys[i]];
                    }
                    else
                    {
                        result = Calc(func, result, dic[keys[i]]);
                    }

                    var str = express.Substring(express.IndexOf(keys[i]) + keys[i].Length);
                    func = GetFunc(str);
                }

            }

            if (result == 0)
                return null;
            return result;
        }

        char GetFunc(string str)
        {
            foreach (var s in str)
            {
                switch (s)
                {
                    case '+':
                    case '-':
                        return s;
                }
            }

            return '\0';
        }

        decimal Calc(char func, decimal val1, decimal val2)
        {
            switch (func)
            {
                case '+':
                    return Plus(val1, val2);
                case '-':
                    return Minus(val1, val2);
            }
            return 0;
        }

        decimal Plus(decimal val1, decimal val2)
        {
            return val1 + val2;
        }

        decimal Minus(decimal val1, decimal val2)
        {
            return val1 - val2;
        }

        private void iPrintPreview_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (Fis.Win.Utils.AppSession.RightsValidata(this.GetType().Name, "Print"))
                theGridControl.ShowPrintPreview();
        }

        private void iExport_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (Fis.Win.Utils.AppSession.RightsValidata(this.GetType().Name, "Export"))
            {
                using (var f = new SaveFileDialog())
                {
                    f.Filter = "EXCEL 文件| *.xls ";

                    if (DialogResult.OK == f.ShowDialog())
                    {
                        theGridControl.ExportToXls(f.FileName);
                        DevExpress.XtraEditors.XtraMessageBox.Show("导出成功");
                    }
                }
            }
        }

        private void iFilter_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ShowFilter();
        }

        protected virtual void ShowFilter()
        { }

        protected virtual void ShowDetial(object state)
        {
        }

        protected virtual void ShowView()
        {

        }

        private void barButtonItem1_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ShowView();
        }

        private void iChangeRange_EditValueChanged(object sender, EventArgs e)
        {
            ChangeRange(Convert.ToInt32(iChangeRange.EditValue));
        }

        protected virtual void ChangeRange(int Range)
        {
            CurrentRange = Range;
        }

        /// <summary>
        /// 绑定会计期间
        /// </summary>
        protected virtual void BindingRange()
        {
            int startRange = Fis.Win.Utils.AppSession.BookStartTime.Month;
            int currentRange = int.Parse(Fis.Win.Utils.AppSession.Range);
            for (int i = startRange; i <= currentRange; i++)
            {
                (iChangeRange.Edit as DevExpress.XtraEditors.Repository.RepositoryItemComboBox).Items.Add(i);
            }
        }
    }
}